package com.aaa.controller;


import com.aaa.Constants;
import com.aaa.POJO.TXT_file_DTO;
import com.aaa.Tool.Split_str;
import com.aaa.Tool.TXT_file_tools;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.*;

@Controller
@RequestMapping(value = "/search")
public class Search {


//    @Autowired
//    private SQL_Mapper sql_mapper;
//
//    @Autowired
//    private Auto_complete_Mapper auto_complete_mapper;
//

    @GetMapping(value = "")
    public String index(Model model) {
    /*
    每次都 new 一个对象出来会不会内存占用过高, 浪费内存?

    GPT 回答:
        在 Java 中，每次都创建新的对象可能会增加内存占用，特别是对于一些不变的常量或配置信息，
        频繁创建新的实例显得不必要且低效。对于这些情况，推荐使用单例模式或者直接使用 static 变量。
        解决方案 1: 使用 static 常量
        如果你有一个常量类，通常会定义所有常量为 static，这样你可以直接通过类名来访问这些常量，而不需要创建实例。
    */
        Constants constants = new Constants();
        String setting_file_path = constants.getSETTING_FILE_PATH();

        try (Scanner scanner = new Scanner(new File(setting_file_path))) {
            while (scanner.hasNextLine()) {
                String line = scanner.nextLine();
                model.addAttribute("txt_folder", line);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return "Search/index.html";
    }


    @GetMapping(value = "/{keyword}")
    public String edit(Model model, @PathVariable String keyword) {
        if (keyword.isEmpty() || keyword.equals(" ")) {
            keyword = "@@@@@@@@@@@@@@";
        }

        /*
        java 给每个中文字符之间加空格, 像下面这样:
        String aaa = "abc 操作系统";  变成 "abc 操 作 系 统"
        英文字符不用, 保持不变

        chatgpt 给出了完美的答案!
        */
        keyword = keyword.replaceAll("([\\u4e00-\\u9fa5])", " $1 ").replaceAll("\\s+", " ").trim();

        ArrayList<TXT_file_DTO> txt_file_dto_list = new ArrayList<>();

        List<TXT_file_DTO> search_result_list = search_word(txt_file_dto_list, keyword);

        // 可能会出现空指针异常
        if (search_result_list != null) {
            Comparator<TXT_file_DTO> byScore = Comparator.comparingInt(TXT_file_DTO::getScore);
            search_result_list.sort(byScore.reversed());  // 对 ulist 的 score 排序
            model.addAttribute("search_result", search_result_list);
        } else {
            model.addAttribute("search_result", Collections.emptyList()); // 或者传递其他默认值
        }

        return "Search/index.html";
    }


    public List<TXT_file_DTO> search_word(List<TXT_file_DTO> txt_file_dto_list, String keyword_string) {
        keyword_string = keyword_string.replace(":", " ").replace("+", " ").replace(".", " ");
        keyword_string = keyword_string.toLowerCase();

        int score = 0;

        TXT_file_tools txt_file_tools = new TXT_file_tools();
        String txt_folder_path = txt_file_tools.get_txt_folder_path();

        HashMap<Integer, Integer> myhashmap = new HashMap<>();
        Split_str split_str = new Split_str();
        File directory = new File(txt_folder_path);

        // 检查目录是否存在
        if (directory.exists() && directory.isDirectory()) {
            // 调用方法输出目录中的所有文件路径
            HashSet<String> all_file_path = txt_file_tools.get_all_file_path(directory);

            for (String file_path : all_file_path) {
                if (file_path.contains("Automatic_completion")) {
                    continue;
                }
//                System.out.println(file_path);
                File file = new File(file_path);
                long filelength = file.length();     //获取文件长度
                byte[] filecontent = new byte[(int) filelength];
                try {
                    FileInputStream in = new FileInputStream(file);
                    in.read(filecontent);
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                String txt_content = new String(filecontent);
                String[] split = txt_content.split(split_str.strrrrrr);
                String title = split[0];
                String content = split[1];
                title = title.trim();
                title = title.toLowerCase();  // 标题 小写
                content = content.trim();  // 去掉两端的空白符号
                TXT_file_DTO txt_file_dto = new TXT_file_DTO();
                String file_name = txt_file_tools.get_name(file_path);

                score = Similarity_comparison(keyword_string, title);

                if (score > 1) {
                    txt_file_dto.setName(file_name);
                    txt_file_dto.setTitle(title);
                    txt_file_dto.setPath(file_path);
                    txt_file_dto.setContent(content);
                    txt_file_dto.setScore(score);
                    // 添加到 list
                    txt_file_dto_list.add(txt_file_dto);
                }
            }
            // 从大到小排序
            Collections.sort(txt_file_dto_list, new Comparator<TXT_file_DTO>() {
                @Override
                public int compare(TXT_file_DTO t1, TXT_file_DTO t2) {
                    return Integer.compare(t1.getScore(), t2.getScore());  // 降序排列
                }
            });

            // 第二个参数是结束索引（不包含），因此取 0 到 Math.min(topN, users.size()) 的范围，以确保不会越界
            int min_number = Math.min(txt_file_dto_list.size(), 25);
            txt_file_dto_list = txt_file_dto_list.subList(txt_file_dto_list.size() - min_number, txt_file_dto_list.size());

            return txt_file_dto_list;

        /*
         来源 :  http://lvhongqiang.com/blog5.html
         我们都习惯于一次把文本的原始内容直接读取到内存中再做处理（暂时不考虑内存大小），这样做效率也会提高。
         很多人用readline()之类的方法，可能需要反复访问文件，
         而且每次readline()都会调用编码转换，降低了速度，
         所以，在已知编码的情况下，
         按字节流方式先将文件都读入内存，
         再一次性编码转换是最快的方式
         这种方法的好处是读取的内容可以彻底保持文件的原貌，
         而且速度应该是最快的，因为只需要调用一次文件访问，字符编码转换也只需要一次
         */

        } else {
            System.out.println("指定的目录不存在或者不是一个目录。");
        }
        return null;
    }


    // 统计相似程度
    public static int Similarity_comparison(String keyStr, String text) {
        String[] key_list = keyStr.split(" ");
        int score____ = 0;
        for (String s : key_list) {
            if (text.contains((s))) {
                score____ = score____ + 20;
            }
        }
//        double percent = (double) keyStr.length() / (keyStr.length() + text.length());
//        score____ = score____ + (int) (percent * 120);  // 百分比 占比越高 分数越高
        return score____;
    }


}



